package abc.base;

import abc.model.ResponseData;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public interface IBaseApi<T extends Serializable, R extends Serializable> {
    /***
     * 打印系统时间
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "time")
    ResponseData timestamp();

    /***
     * 根据ID获取数据
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "{id}", method = RequestMethod.GET  )
    ResponseData doGet(@PathVariable("id") Long id);

    /***
     * 查询分页数据
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "query/{pageIndex}/{pageSize}", method = RequestMethod.POST  )
    ResponseData doQueryPage(@RequestBody T queryData, @PathVariable("pageIndex") Long pageIndex, @PathVariable("pageSize") Long pageSize);

    /***
     * 查询数据
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "query", method = RequestMethod.POST  )
    ResponseData<List<R>> doQuery(@RequestBody T queryData);

    /***
     * 查询是否存在数据
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "exist", method = RequestMethod.POST  )
    ResponseData<Boolean> doExist(@RequestBody T queryData);

    /***
     * 查询统计数据
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "count", method = RequestMethod.POST  )
    ResponseData<Long> doCount(@RequestBody T queryData);

    /***
     * 新增数据 (可批量)
     * @param postData 提交参数（数组）
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "insert", method = RequestMethod.PUT  )
    ResponseData doInsert(@RequestBody List<T> postData) throws IOException, SQLException;

    /***
     * 修改数据
     * @param id 计算字段
     * @param postData 提交参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "{id}", method = RequestMethod.PUT  )
    ResponseData<Boolean> doUpdate(@PathVariable("id") Long id, @RequestBody T postData) throws IOException, SQLException;

    /***
     * 删除数据
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "{id}", method = RequestMethod.DELETE  )
    ResponseData<Boolean> doDelete(@PathVariable("id") Long id) throws SQLException;

    /***
     * 批量删除数据
     * @param idList id列表
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "delete", method = RequestMethod.DELETE  )
    ResponseData<Boolean> deleteByIds(@RequestBody List idList) throws SQLException;

    /***
     * 查询指定字段最小值
     * @param field 计算字段
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "min/{field}", method = RequestMethod.POST )
    ResponseData<String> doGetMin(@PathVariable("field") String field, @RequestBody T queryData);

    /***
     * 查询指定字段最大值
     * @param field 计算字段
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "max/{field}", method = RequestMethod.POST )
    ResponseData<String> doGetMax(@PathVariable("field") String field, @RequestBody T queryData);

    /***
     * 查询指定字段之和
     * @param field 计算字段
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "sum/{field}", method = RequestMethod.POST )
    ResponseData<String> doGetSum(@PathVariable("field") String field, @RequestBody T queryData);

    /***
     * 查询指定字段平均值
     * @param field 计算字段
     * @param queryData 查询参数
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "avg/{field}", method = RequestMethod.POST )
    ResponseData<String> doGetAvg(@PathVariable("field") String field, @RequestBody T queryData);

    /***
     * 上传文件到指定字段
     * @param field 路径存放字段
     * @param id 数据id
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "{field}/upload/{id}", method = RequestMethod.POST )
    Mono<ResponseData> doUpload(@PathVariable("field") String field, @PathVariable("id") Long id,
                                @RequestPart("file") Flux<FilePart> file) throws Exception;

    /***
     * 上传文件
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "/upload", method = RequestMethod.POST )
    Mono<ResponseData> doJustUpload(@RequestPart("file") Flux<FilePart> file) throws Exception;

    /***
     * 插入表单数据（支持上传文件）
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "form/insert", method = RequestMethod.PUT )
    Mono<ResponseData> doPostFormDataAndInsert(ServerWebExchange exchange) throws Exception;

    /***
     * 下载指定字段路径文件
     * @param field 路径存放字段
     * @param id 数据id
     * @param index 文件列表索引
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "download/{field}/{id}/{index}", method = RequestMethod.GET  )
    ResponseEntity<byte[]> doDownload(@PathVariable("field") String field, @PathVariable("id") Long id, @PathVariable("index") Integer index) throws Exception;

    /***
     * 视频文件播放
     * @param field 路径存放字段
     * @param id 数据id
     * @param index 文件列表索引
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "play/{field}/{id}/{index}", method = RequestMethod.GET )
    Mono<Void> doPlayVideo(@PathVariable("field") String field, @PathVariable("id") Long id, @PathVariable("index") Integer index, ServerWebExchange exchange) throws Exception;

    /***
     * 导出数据
     * @param queryData 查询参数
     * @throws Exception
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "export", method = RequestMethod.POST )
    ResponseEntity<byte[]> doExportExcel(@RequestBody T queryData) throws Exception;

    /***
     * 导入Excel
     * @param file 上传导入文件
     * @return
     */
    @ResponseBody
    @RequestMapping( value = "import", method = {RequestMethod.POST} )
    Mono<ResponseData<String>> doImportExcel(@RequestPart("file") Flux<FilePart> file) throws Exception;
}

